package response

import (
	"math"

	"github.com/goravel/framework/contracts/http"
)

// Response 通用的响应结构体
type Response[T any] struct {
	Code    int    `json:"code"`            // 状态码
	Data    T      `json:"data"`            // 数据部分
	Message string `json:"message"`         // 消息
	Token   string `json:"token,omitempty"` // Token，可选字段
}

// PaginationMeta 分页元信息
type PaginationMeta struct {
	Total    int64 `json:"total"`     // 总记录数
	Page     int   `json:"page"`      // 当前页
	PerPage  int   `json:"per_page"`  // 每页数量
	LastPage int   `json:"last_page"` // 最后一页
}

// PaginationResponse 分页响应结构体
type PaginationResponse[T any] struct {
	Data T              `json:"data"` // 数据部分
	Meta PaginationMeta `json:"meta"` // 分页元信息
}

// Paginate 返回分页响应
// ctx: HTTP 上下文
// data: 分页数据
// total: 总记录数
// page: 当前页
// perPage: 每页数量
// message: 可选的自定义消息，默认为 "Success"
func Paginate[T any](ctx http.Context, data T, total int64, page, perPage int, message ...string) http.Response {

	lastPage := int(math.Ceil(float64(total) / float64(perPage)))

	paginationData := PaginationResponse[T]{
		Data: data,
		Meta: PaginationMeta{
			Total:    total,
			Page:     page,
			PerPage:  perPage,
			LastPage: lastPage,
		},
	}

	// 返回成功响应
	return Success(ctx, paginationData, message...)
}

// Success 返回成功的响应
// data: 返回的数据
// message: 可选的自定义消息，默认为 "Success"
func Success[T any](ctx http.Context, data T, message ...string) http.Response {
	msg := getMessage("Success", message...)
	return jsonResponse(ctx, http.StatusOK, data, msg)
}

// Fail 返回通用的失败响应
// code: HTTP 状态码
// msg: 可选的自定义消息，默认为状态码对应的默认消息
func Fail(ctx http.Context, code int, msg ...string) http.Response {
	message := getMessage(getDefaultMessage(code), msg...)
	return jsonResponse[any](ctx, code, nil, message)
}

func Abort(ctx http.Context, code int, msg ...string) {
	message := getMessage(getDefaultMessage(code), msg...)
	err := ctx.Response().Json(code, Response[any]{
		Code:    code,
		Data:    nil,
		Message: message,
	}).Abort()
	if err != nil {
		return
	}
}

// Json 返回自定义的 JSON 响应
// code: HTTP 状态码
// data: 返回的数据
// msg: 可选的自定义消息，默认为状态码对应的默认消息
func Json[T any](ctx http.Context, code int, data T, msg ...string) http.Response {
	message := getMessage(getDefaultMessage(code), msg...)
	return jsonResponse(ctx, code, data, message)
}

// jsonResponse 统一的 JSON 响应生成函数
func jsonResponse[T any](ctx http.Context, code int, data T, msg string) http.Response {
	// token, ok := ctx.Value(constants.TokenPrefix).(string)
	// if !ok {
	// 	token = ""
	// }
	return ctx.Response().Json(code, Response[T]{
		Code:    code,
		Data:    data,
		Message: msg,
		// Token:   token,
	})
}

// getMessage 获取最终的消息
// defaultMsg: 默认消息
// messages: 可选的自定义消息
func getMessage(defaultMsg string, messages ...string) string {
	if len(messages) > 0 {
		return messages[0]
	}
	return defaultMsg
}

// getDefaultMessage 根据状态码返回默认消息
func getDefaultMessage(code int) string {
	switch code {
	case http.StatusOK:
		return "Success"
	case http.StatusBadRequest:
		return "Bad request"
	case http.StatusNotFound:
		return "Resource not found"
	case http.StatusInternalServerError:
		return "Internal server error"
	default:
		return ""
	}
}
